package com.lanqiao.controller;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 张建平 on 2018/10/6 15:20
 */
@Controller
@RequestMapping("/file")
public class FileController implements ServletContextAware{

    static Logger logger = Logger.getLogger(FileController.class);

    ServletContext servletContext;
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");

    //案例1： 必须使用@RequestParam注解指定参数
    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public String upload(@RequestParam("upload") CommonsMultipartFile file, ModelMap modelMap) {
        // 得到上传的文件
        FileItem fileItem = file.getFileItem();

        // 获得文件MIME类型: image/jpg, text/html, text/css, text/js
        String contentType = file.getContentType();
        logger.debug("文件类型" + contentType);

        // 上传文件的原始文件名，注意多人上传可会有同名的文件
        String originalFilename = file.getOriginalFilename();
        logger.debug("原文件名" + originalFilename);

        //生成上传后的新文件名：原文件名_YYYYMMDD_HHMMSS.txt
        String destFileName = StringUtils.substringBefore(originalFilename,".")
                + "_"+ sdf.format(new Date()) + "."+StringUtils.substringAfter(originalFilename, ".");
        logger.debug("目标文件名" + destFileName);

        // jsp: application = ServletContext
        String realPath = this.servletContext.getRealPath("/upload");
        File destFile = new File(realPath, destFileName);
        logger.debug("目标文件" + destFile.getPath());

        try {
            fileItem.write(destFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //
        modelMap.addAttribute("file", file);
        modelMap.addAttribute("destPath", destFile.getPath());
        return "forward:/upload_success.jsp";
    }


    /**
     * 查看下载的文件 列表
     * @param modelMap
     * @return
     */
    @RequestMapping("/list_files")
    public String listFiles(ModelMap modelMap) {
        String uploadPath = this.servletContext.getRealPath("/upload");
        File uploadDirectory = new File(uploadPath);
        // 得到上传目录中所有符合扩展名的文件名列表
        String[] fileNames = uploadDirectory.list((dir, name) -> {
            return StringUtils.endsWithAny(name, ".txt", ".jpg", ".jpeg", ".gif", ".doc", ".xls");
        });

        modelMap.addAttribute("fileNames", fileNames);
        return "forward:/list_files.jsp";
    }


    /**
     * 下载
     * @param fileName
     * @param modelMap
     * @return
     */
    @RequestMapping("/download")
    public void download(String fileName, HttpServletResponse response, ModelMap modelMap) {
        String uploadPath = this.servletContext.getRealPath("/upload");
        File downloadFile = new File(uploadPath,fileName);
        logger.debug("下载的文件：" + downloadFile);

        //
        response.reset();
        //设置下载文件的头部信息， 以附件的形式下载filename为客户端弹出的下载框中的默认文件名
        response.setHeader("Content-Disposition", "attachment; filename="+fileName);
        response.setContentType("application/octet-stream; charset=utf-8"); //application/octet-stream表示*.rar文件

        try {
            //application/octet-stream表示*.rar文件
            byte[] buf = FileUtils.readFileToByteArray(downloadFile);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(buf);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
        /*
            if(controller instanceof ServletContextAware){
                    ((ServletContextAware)controller).setServletContext(?);
            }
        *
        * */
    }
}
